using System;
using System.Collections.Generic;
using System.Text;

namespace RGuang.Kit
{
    /// <summary>
    /// 随机类
    /// 
    /// </summary>
    public static class RandomKit
    {
        #region 洗牌
        /// <summary>
        ///  洗牌
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lst"></param>
        public static void RandomArray<T>(List<T> lst)
        {
            if (lst == null) throw new ArgumentNullException();

            System.Random rand = new System.Random();
            for (int i = lst.Count - 1; i >= 0; i--)
            {
                int j = rand.Next(i + 1);
                T tmp = lst[i];
                lst[i] = lst[j];
                lst[j] = tmp;
                //if (i % 100 == 0) GC.Collect();
            }

        }

        /// <summary>
        ///  洗牌
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arr"></param>
        public static void RandomArray<T>(T[] arr)
        {
            if (arr == null) throw new ArgumentNullException();

            System.Random rand = new System.Random();
            for (int i = arr.Length - 1; i >= 0; i--)
            {
                int j = rand.Next(i + 1);
                T tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
                //if (i % 100 == 0) GC.Collect();
            }

        }
        #endregion

        #region 随机中文名字
        /// <summary>
        /// 单姓氏库
        /// </summary>

        public static List<string> SingleSurnames = new List<string>
        {
            "王", "李", "张", "刘", "陈", "杨", "赵", "黄", "周", "吴",
            "徐", "孙", "胡", "朱", "高", "林", "何", "郭", "马", "罗",
            "梁", "宋", "郑", "谢", "韩", "唐", "冯", "于", "董", "萧",
            "程", "曹", "袁", "邓", "许", "傅", "沈", "曾", "彭", "吕",
            "苏", "卢", "蒋", "蔡", "贾", "丁", "魏", "薛", "叶", "阎",

            "余", "潘", "杜", "戴", "夏", "钟", "田", "姜", "范", "方",
            "石", "姚", "谭", "廖", "邹", "熊", "金", "陆", "郝", "孔",
            "白", "崔", "康", "毛", "邱", "秦", "江", "史", "顾", "侯",
            "邵", "孟", "龙", "万", "段", "雷", "钱", "汤", "尹", "黎",
            "易", "常", "武", "乔", "贺", "赖", "龚", "文", "庞", "樊",

            "兰", "殷", "施", "陶", "洪", "翟", "安", "颜", "倪", "严",
            "牛", "温", "姬", "季", "俞", "章", "鲁", "葛", "伍", "韦",
            "申", "尤", "毕", "聂", "丛", "焦", "向", "柳", "邢", "路",
            "岳", "齐", "沿", "梅", "莫", "庄", "辛", "管", "祝", "左",
            "涂", "谷", "祁", "时", "舒", "耿", "牟", "卜", "商", "佘",

            "景", "木", "詹", "狄", "米", "贝", "明", "边", "计", "伏",
            "成", "谈", "闻", "纪", "屈", "项", "阮", "蓝", "闵", "席",
            "麻", "强", "娄", "危", "童", "盛", "刁", "丘", "骆", "卓",
            "凌", "霍", "虞", "支", "柯", "宰", "经", "房", "裘", "干",
            "解", "应", "宗", "宣", "能", "郁", "单", "杭", "包", "苍",

            "吉", "燕", "通", "桂", "裴", "荣", "翁", "荀", "羊", "冉",
            "甄", "曲", "家", "封", "国", "羿", "储", "靳", "柴", "晏",
            "松", "井", "富", "巫", "乌", "巴", "弓", "牧", "古", "山",
            "车", "尚", "鱼", "全", "容", "班", "农", "秋", "仲", "伊",
            "宫", "宁", "仇", "栾", "暴", "甘", "步", "厉", "戎", "祖",

            "符", "束", "幸", "司", "韶", "艾", "蓟", "习", "咸", "苗",
            "年", "宿", "花", "居", "鹿", "从", "鄂", "索", "郦", "瞿",
            "衡", "屠", "蒙", "池", "阴", "胥", "双", "戈", "终", "党",
            "皮", "戚", "巢", "扶", "堵", "都", "别", "尸", "充", "墨",
            "广", "桑", "禄", "满", "寿", "敖", "慕", "沙", "蔚", "佟",
        };
        /// <summary>
        /// 复姓氏库 
        /// </summary>
        public static List<string> CompoundSurnames = new List<string>()
        {
            "万俟",  "司马",  "上官",  "欧阳",  "夏侯",  "诸葛",  "闻人",  "东方",
            "赫连",  "皇甫",  "尉迟",  "公羊",  "澹台",  "公冶",  "宗政",  "濮阳",
            "淳于",  "单于",  "太叔",  "申屠",  "公孙",  "仲孙",  "轩辕",  "令狐",
            "钟离",  "宇文",  "长孙",  "慕容",  "鲜于",  "闾丘",  "司徒",  "司空",
            "司寇",  "子车",  "颛孙",  "端木",  "巫马",  "公西",  "乐正",  "公良",
            "拓跋",  "宰父",  "段干",  "百里",  "东郭",  "南门",  "呼延",  "归海",
            "羊舌",  "梁丘",  "左丘",  "东门",  "西门",  "第五",  "有莘",  "南宫",
        };

        /// <summary>
        ///常用男字库 
        /// </summary>
        public static readonly List<string> ManCharacters = new List<string>
        {
            "伟", "勇", "军", "杰", "涛", "明", "超", "强", "磊", "洋",
            "俊", "博", "文", "健", "建", "华", "志", "国", "子", "德",
            "民", "晨", "宇", "浩", "阳", "飞", "鹏", "斌", "龙", "林",
            "泽", "轩", "睿", "祺", "峰", "川", "凯", "波", "云", "羽",

            "昊", "傲", "天", "灵", "常", "成", "一", "铁", "新", "梓",
            "郎", "空", "英", "少", "邵", "兵", "武", "世", "士", "豪",
            "古", "甲", "烈", "壮", "威", "雄", "刚", "毅", "卿", "业",
            "义", "翔", "辉", "正", "白", "安", "虎", "剑", "儿", "敬",

            "霸", "忠", "公", "信", "诚", "乐", "晓", "孝", "智", "山",
            "海", "立", "法", "东", "和", "赞", "言", "礼", "力", "宏",
        };
        /// <summary>
        /// 常用女字库 
        /// </summary>
        public static List<string> LadyCharacters = new List<string>
        {
            "芳", "娜", "敏", "静", "丽", "艳", "娟", "英", "慧", "秀",
            "玲", "雪", "莹", "洁", "颖", "丹", "红", "雯", "佳", "玉",
            "婷", "欣", "悦", "璐", "瑶", "琳", "萍", "月", "美", "嫣",
            "琴", "惠", "雅", "真", "淑", "珍", "贤", "瑾", "岚", "霞",

            "倩", "宁", "菲", "薇", "兰", "晶", "蕾", "韵", "冰", "花",
            "妹", "宣", "妃", "燕", "彩", "梦", "妍", "媛", "婵", "珠",
            "蝶", "樱", "凤", "儿", "心", "芹", "言", "乐", "翠", "紫",
            "文", "安", "环", "盈", "灵", "蓉", "莺", "白", "菊", "银",

            "霜", "如", "娇", "姬", "琼", "双", "龄", "茹", "巧", "娘",
            "凝", "婉", "绾", "颜", "苗", "茜", "琪", "萌", "鱼", "羽",
        };
        /// <summary>
        /// 随机一个带姓氏的中文名字
        /// </summary>
        /// <param name="NameCount">除姓氏外的名字字数【默认1个】</param>
        /// <param name="isLady">true随机女士名，false随机男士名，默认false</param>
        /// <returns></returns>
        public static string GetRandomNameWithSurname(int NameCount = 1, bool isLady = false)
        {
            //姓
            StringBuilder sb = new StringBuilder(GetRandomSurname(GetRandomByCrypto()));
            //字库选择
            var data = isLady ? LadyCharacters : ManCharacters;
            //生成指定数量名
            for (int i = 0; i < NameCount; i++)
            {
                sb.Append(GetRandomCharacter(data, GetRandomByCrypto()));
            }

            return sb.ToString();
        }
        /// <summary>
        /// 随机获取一个带姓氏的中文名
        /// 中文名带姓氏、单姓氏格式ABB，复姓格式ABCC。
        /// </summary>
        /// <param name="isLady">true随机女士名，false随机男士名，默认false</param>
        /// <returns></returns>
        public static string GetRandomNameFormatABB(bool isLady = false)
        {
            //姓
            StringBuilder sb = new StringBuilder(GetRandomSurname(GetRandomByCrypto()));
            //字库选择
            var data = isLady ? LadyCharacters : ManCharacters;

            var ch = GetRandomCharacter(data, GetRandomByCrypto());
            sb.Append(ch);
            sb.Append(ch);

            return sb.ToString();
        }
        /// <summary>
        /// 获取随机姓氏（单姓或复姓）
        /// </summary>
        public static string GetRandomSurname(int randomSeed = 0)
        {
            randomSeed = randomSeed == 0 ? GetRandomByCrypto() : randomSeed;
            System.Random random = new System.Random(GetRandomByCrypto());

            // 70%概率使用单姓，30%概率使用复姓
            return random.Next(10) < 7 ? GetRandomSingleSurname(randomSeed) : GetRandomCompoundSurname(randomSeed);
        }
        /// <summary>
        /// 获取随机单姓
        /// </summary>
        public static string GetRandomSingleSurname(int randomSeed = 0) => GetRandomCharacter(SingleSurnames, randomSeed);
        /// <summary>
        /// 获取随机复姓
        /// </summary>
        public static string GetRandomCompoundSurname(int randomSeed = 0) => GetRandomCharacter(CompoundSurnames, randomSeed);
        /// <summary>
        /// 从指定字符列表中获取随机字符
        /// <param name="characters">字库</param>
        /// </summary>
        public static string GetRandomCharacter(List<string> characters, int randomSeed = 0)
        {
            if (characters == null || characters.Count == 0)
            {
                return string.Empty;
            }

            randomSeed = randomSeed == 0 ? GetRandomByCrypto() : randomSeed;
            System.Random random = new System.Random(randomSeed);

            int index = random.Next(0, characters.Count);
            return characters[index];
        }
        #endregion


        /// <summary>
        /// 获得一串随机字符串【字符串包含大小写字母和数字】
        /// </summary>
        /// <param name="str_len">参数str_len指定获取的长度</param>
        public static string GetRandStrByLength(uint str_len)
        {
            System.Random r = new System.Random(GetRandomByCrypto());

            string str = null;
            str += "0123456789";
            str += "abcdefghijklmnopqrstuvwxyz";
            str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

            string s = null;

            for (int i = 0; i < str_len; i++)
            {
                s += str.Substring(r.Next(0, str.Length - 1), 1);
            }
            return s;
        }

        /// <summary>
        /// 利用安全加密算法的伪随机，比普通Random更复杂的随机
        /// </summary>
        /// <returns>返回一个随机后的整数，可做为随机种子</returns>
        public static int GetRandomByCrypto()
        {
            byte[] b = new byte[4];
            new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
            return System.BitConverter.ToInt32(b, 0);
        }



    }

}
